package org.dev.hi.hiui.search

import android.content.Context
import android.graphics.Color
import android.text.Editable
import android.text.InputFilter
import android.text.TextUtils
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import org.dev.hi.hiui.R
import org.dev.hi.hiui.iconFont.IconFontTextView
import org.dev.hi.library.util.MainHandler
import java.lang.IllegalStateException

/**
 * Author WenPing
 * CreateTime 2021/8/24.
 * Description:
 */
class HiSearchView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyle: Int = 0
) : RelativeLayout(context, attributeSet, defStyle) {

    // 创建常量 显示左/右
    companion object {
        const val LEFT = 1
        const val CENTER = 0

        const val DEBOUNCE_TRIGGER_DURATION = 200L
    }

    private var simpleTextWatcher: SimpleTextWatcher? = null

    var editText: EditText? = null

    // 搜索小图标 和默认提示语,以及容器
    private var searchIcon: IconFontTextView? = null
    private var hintTv: TextView? = null
    private var searchIconHintContainer: LinearLayout? = null

    // 右侧清除小图标
    private var clearIcon: IconFontTextView? = null

    // 关键词
    private var keywordContainer: LinearLayout? = null
    private var keywordTv: TextView? = null
    private var kwClearIcon: IconFontTextView? = null

    // 解析属性值,获得 Attrs
    private var viewAttrs = AttrsParse.parseAttrs(context, attributeSet)

    init {
        //初始化editText  --create-bind property --addview
        initEditText()
        //初始化右侧一键清楚地小按钮   create-bind property --addview
        initClearIcon()
        //初始化 默认的提示语 和 searchIcon  create-bind property --addview
        initSearchIconHintContainer()

        background = viewAttrs.searchBackground

        editText?.addTextChangedListener(object : SimpleTextWatcher() {
            override fun afterTextChanged(text: Editable?) {
                val hasContent = text?.trim()?.length ?: 0 > 0
                changeVisibility(searchIcon, hasContent)
                changeVisibility(searchIconHintContainer, !hasContent)

                // 移除debounceRunnable
                if (simpleTextWatcher != null) {
                    MainHandler.remove(debounceRunnable)
                }
            }
        })

    }

    private val debounceRunnable = Runnable {
        if (simpleTextWatcher != null) {
            // editText 输入完毕后显示当前的文字
            simpleTextWatcher!!.afterTextChanged(editText?.text)
        }
    }

    fun setClearIconClickListener(listener: OnClickListener) {
        clearIcon?.setOnClickListener {
            editText?.text = null
            changeVisibility(clearIcon, false)
            changeVisibility(searchIcon, true)
            changeVisibility(hintTv, true)
            changeVisibility(searchIconHintContainer, true)

            listener.onClick(it)
        }
    }

    fun setDebounceTextChangedListener(simpleTextWatcher: SimpleTextWatcher) {
        this.simpleTextWatcher = simpleTextWatcher
    }

    fun setHintText(hintText: String) {
        hintTv?.text = hintText
    }

    /**
     * 设置关键词
     */
    fun setKeyWord(keyword: String?, listener: OnClickListener) {
        // 用户点击联想面板的时候,会调用该方法,把关键词设置到搜索框上面
        ensureKeywordContainer()
        toggleSearchViewsVisibility(true)

        editText?.text = null
        keywordTv?.text = keyword
        kwClearIcon?.setOnClickListener {
            // 点击了清除按钮,要回复默认提示语views的显示
            toggleSearchViewsVisibility(false)
            listener.onClick(it)
        }
    }

    /**
     * 切换 搜索控件们的显示效果
     */
    private fun toggleSearchViewsVisibility(showWord: Boolean) {
        changeVisibility(editText, !showWord)
        changeVisibility(clearIcon, false)
        changeVisibility(keywordContainer, !isShown)
        changeVisibility(searchIcon, !isShown)
        changeVisibility(hintTv, !isShown)
        changeVisibility(keywordContainer, showWord)
    }

    /**
     * keywordContainer 水平布局,用于添加 关键词显示,清除按钮
     */
    private fun ensureKeywordContainer() {
        if (keywordContainer != null) return

        if (!TextUtils.isEmpty(viewAttrs.keywordClearIcon)) {
            kwClearIcon = IconFontTextView(context, null)
            kwClearIcon?.apply {
                setTextSize(
                    TypedValue.COMPLEX_UNIT_PX,
                    viewAttrs.keywordSize
                )
                setTextColor(viewAttrs.keywordColor)
                text = viewAttrs.keywordClearIcon
                id = R.id.id_search_keyword_clear_icon
                setPadding(
                    viewAttrs.iconPadding * 2,
                    viewAttrs.iconPadding,
                    viewAttrs.iconPadding * 2,
                    viewAttrs.iconPadding
                )
            }
        }
        keywordTv = TextView(context)
        keywordTv?.apply {
            setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                viewAttrs.keywordSize
            )
            setTextColor(viewAttrs.keywordColor)
            includeFontPadding = false
            isSingleLine = true
            ellipsize = TextUtils.TruncateAt.END
            filters = arrayOf(
                // 设置最长长度
                InputFilter.LengthFilter(viewAttrs.keywordMaxLen)
            )
            id = R.id.id_search_keyword_text_view
            setPadding(
                viewAttrs.iconPadding,
                viewAttrs.iconPadding / 2,
                if (kwClearIcon == null) viewAttrs.iconPadding else 0,
                viewAttrs.iconPadding / 2
            )

            keywordContainer = LinearLayout(context)
            keywordContainer?.apply {
                orientation = LinearLayout.HORIZONTAL
                gravity = Gravity.CENTER
                background = viewAttrs.keywordBackground
                addView(
                    keywordTv,
                    LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT
                    )
                )
            }

            if (kwClearIcon != null) {
                keywordContainer?.addView(
                    kwClearIcon,
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
                )
            }

            val kwParams = LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT
            )
            kwParams.apply {
                addRule(CENTER_VERTICAL)
                addRule(ALIGN_PARENT_LEFT)
                leftMargin = viewAttrs.iconPadding
                rightMargin = viewAttrs.iconPadding
            }
            addView(keywordContainer, kwParams)
        }
    }


    /**
     * 初始化 搜索组件提示相关
     */
    private fun initSearchIconHintContainer() {
        // hint--->start
        hintTv = TextView(context)
        hintTv?.setTextColor(viewAttrs.hintTextColor)
        hintTv?.setTextSize(TypedValue.COMPLEX_UNIT_PX, viewAttrs.hintTextSize)
        hintTv?.isSingleLine = true
        hintTv?.text = viewAttrs.hintText
        hintTv?.id = R.id.id_search_hint_view
        // hint<---end
        // search icon--->start
        searchIcon = IconFontTextView(context, null)
        searchIcon?.setTextSize(TypedValue.COMPLEX_UNIT_PX, viewAttrs.searchIconSize)
        searchIcon?.setTextColor(viewAttrs.searchTextColor)
        searchIcon?.text = viewAttrs.searchIcon
        searchIcon?.id = R.id.id_search_icon
        searchIcon?.setPadding(viewAttrs.iconPadding, 0, viewAttrs.iconPadding, 0)
        // search icon<---end
        // icon hint container---start
        // 水平布局
        searchIconHintContainer = LinearLayout(context)
        searchIconHintContainer?.apply {
            orientation = LinearLayout.HORIZONTAL
            gravity = Gravity.CENTER

            addView(searchIcon)
            addView(hintTv)
        }
        val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
        params.addRule(CENTER_VERTICAL)
        // viewAttrs.gravity 枚举;
        when (viewAttrs.gravity) {
            CENTER -> params.addRule(CENTER_IN_PARENT)
            LEFT -> params.addRule(ALIGN_PARENT_LEFT)
            else -> throw IllegalStateException("not support gravity for now.")
        }
        addView(searchIconHintContainer, params)
        // icon hint container<---end
    }

    /**
     * 初始化 清除按钮
     */
    private fun initClearIcon() {
        if (TextUtils.isEmpty(viewAttrs.clearIcon)) return

        clearIcon = IconFontTextView(context, null)
        clearIcon?.setTextSize(
            TypedValue.COMPLEX_UNIT_PX,
            viewAttrs.clearIconSize
        )
        clearIcon?.text = viewAttrs.clearIcon
        clearIcon?.setTextColor(viewAttrs.searchTextColor)
        clearIcon?.setPadding(viewAttrs.iconPadding, 0, viewAttrs.iconPadding, 0)

        // 尺寸参数
        val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
        params.addRule(CENTER_VERTICAL)
        params.addRule(ALIGN_PARENT_RIGHT)

        // 默认隐藏,只有当输入文字时才会显示
        changeVisibility(clearIcon, false)
        clearIcon?.id = R.id.id_search_clear_icon

        addView(clearIcon, params)

    }

    /**
     * 初始化 EditText
     */
    private fun initEditText() {
        editText = EditText(context)
        editText?.setTextColor(viewAttrs.searchTextColor)
        editText?.setBackgroundColor(Color.TRANSPARENT)
        // 设置输入框的文字大小
        editText?.setTextSize(TypedValue.COMPLEX_UNIT_PX, viewAttrs.searchTextSize)
        // 防止文字输入过于靠近边框
        editText?.setPadding(viewAttrs.iconPadding, 0, viewAttrs.iconPadding, 0)

        // 给edittext设置在相对布局中的显示规则
        val params = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        params.addRule(CENTER_VERTICAL)
        addView(editText, params)
    }

    private fun changeVisibility(view: View?, show: Boolean) {
        view?.visibility = if (show) VISIBLE else GONE
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        MainHandler.remove(debounceRunnable)
    }

    fun getKeywrod(): String = keywordTv?.text.toString()


}